#include "cfg.h"
#include "task.h"
#include "driver_uart.h"
#include "cm_backtrace.h"
SysInf_s gSysInf;
FaultInf_s gFaultInf;
TempLunchInf_s gTempLunchInf;
ADC_AppData stADC_AppData;

TADCSamplingData ADCSamplingData;

TAjustData ConfigAjustData[ADC_CHANNEL_AMOUNT];

/* USER CODE END 0 */

void CalKBValue(TAjustData* pAjustData) {
	// k = (y1- y2) /(x1 -x2)  b = (x1y2- y1x2) / (x1-x2)
	pAjustData->k = (float)(pAjustData->HightPoint.i32Value - pAjustData->LowPoint.i32Value) /
	                ((float)pAjustData->HightPoint.usADVlaue - (float)pAjustData->LowPoint.usADVlaue);

	pAjustData->b = ((float)pAjustData->HightPoint.usADVlaue * (float)pAjustData->LowPoint.i32Value -
	                 (float)pAjustData->HightPoint.i32Value * (float)pAjustData->LowPoint.usADVlaue) /
	                ((float)pAjustData->HightPoint.usADVlaue - (float)pAjustData->LowPoint.usADVlaue);
}


int32_t CalAnalogValue(float fADValue, TAjustData* pAjustData) {
	return (int32_t)((pAjustData->k* fADValue) + pAjustData->b);
}


void SetSysDefaultConfig(void) {
	uint8_t DataSubscript = 0, i = 0;
	/*ADC_current*/
	DataSubscript = ADC_CONTROL_CURRENT;
	ConfigAjustData[DataSubscript].HightPoint.usADVlaue = 80;
	ConfigAjustData[DataSubscript].HightPoint.i32Value = 5050;
	ConfigAjustData[DataSubscript].LowPoint.usADVlaue = 0;
	ConfigAjustData[DataSubscript].LowPoint.i32Value = 0;

	/*ADC_voltage*/
	DataSubscript = ADC_BAT_VOLTAGE;
	ConfigAjustData[DataSubscript].HightPoint.usADVlaue = 3380;
	ConfigAjustData[DataSubscript].HightPoint.i32Value = 7400;
	ConfigAjustData[DataSubscript].LowPoint.usADVlaue = 0;
	ConfigAjustData[DataSubscript].LowPoint.i32Value = 0;

	for (i = 0; i < ADC_CHANNEL_AMOUNT; i++) {
		CalKBValue(&ConfigAjustData[i]);
	}
}


void filteringProcessADC(uint8_t ADC_Chanle, float alpha, float* bufFilter, uint16_t* buf, uint16_t lenth) {
	static float odata[13]; 
	static uint8_t first_flag[13];

	float tempValue = 0;
	int i = 0;
	if (first_flag[ADC_Chanle] == 0) {
		odata[ADC_Chanle] = buf[0];
		first_flag[ADC_Chanle] = 1;
	}
	for (i = 0; i < lenth; i++) {
		tempValue = (float)buf[i];
		odata[ADC_Chanle] = (1 - alpha) * odata[ADC_Chanle] + alpha * tempValue;
		bufFilter[i] = odata[ADC_Chanle];
	}
}


float GetAverage(float* pDat, uint16_t wLen) {
	uint16_t i;
	float buf = 0, max, min;
	max = 0;
	min = 65535;
	for (i = 0; i < wLen; i++) {
		buf += pDat[i];
		if (max < pDat[i]) {
			max = pDat[i];
		}
		if (min > pDat[i]) {
			min = pDat[i];
		}
	}
	buf -= max;
	buf -= min;
	return buf / (wLen - 2);
}


void ADC_Process(ADC_AppData* pCB) {
	static uint16_t tempBuf[ADC_SAMPLING_NUM] = {0};
	uint16_t  j = 0, k = 0;
	int32_t *pi32Analog = &ADCSamplingData.i32CortrolCurrent;
	static float tempBuf_filter[ADC_SAMPLING_NUM] = {0};
	for (k = 0; k < 2; ++k) {
		for (j = 0; j < ADC_SAMPLING_NUM; j++) {
			tempBuf[j] = pCB->stADC_DATA_STR[0].totalADCValue[j][k];
		}

		filteringProcessADC(k, ALPHA_1HZ, tempBuf_filter, tempBuf, ADC_SAMPLING_NUM);

		pCB->stADC_DATA_STR[0].filterADCValue[k] = GetAverage(tempBuf_filter, ADC_SAMPLING_NUM); // ��������ƽ��ֵ
		for (j = 0; j < ADC_CHANNEL_AMOUNT; j++) {
			pi32Analog[j] = CalAnalogValue(pCB->stADC_DATA_STR[0].filterADCValue[j], &ConfigAjustData[j]);
		}
	}
}

extern void fault_test_by_unalign(void);
extern void fault_test_by_div0(void);

void SysInit(void) {
	memset(&gSysInf, 0x00, sizeof(gSysInf));
	memset(&gFaultInf, 0x00, sizeof(gFaultInf));
	memset(&stADC_AppData, 0x00, sizeof(TADCSamplingData));
	gTempLunchInf.system = &gSysInf;
	gTempLunchInf.fault = &gFaultInf;
	TaskParaInit();   
	ProjectTaskCreat();
	SetSysDefaultConfig();
	UART4_Init();
	cm_backtrace_init("CmBacktrace", HARDWARE_VERSION, SOFTWARE_VERSION);
	fault_test_by_div0();	
}
